package proxy;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.SocketException;
import java.util.Collections;
import java.util.List;
import java.util.Vector;

import message.response.MessageResponse;

public class ClientDispatcher extends Thread {
	
	private Proxy proxy;
	private boolean listening;
	
	private List<ClientWorker> workers;
	
	private ServerSocket serverSocket;
	
	public ClientDispatcher(Proxy proxy) {
		this.proxy = proxy;
		workers = Collections.synchronizedList(new Vector<ClientWorker>());
		
		try {
			serverSocket = new ServerSocket(this.proxy.getTcpPort());
		} catch (IOException e) {
			System.out.println(new MessageResponse("Error: An unexpected error occurred!"));
		}
	}
	
	public void shutdown() {
		
		listening = false;
		
		for (ClientWorker worker : workers)
			worker.shutdown();
		
		try {
			
			if (serverSocket != null && !serverSocket.isClosed())
				serverSocket.close();

			serverSocket = null;

		} catch (IOException e) {
			System.out.println(new MessageResponse("Error: An unexpected error occurred!"));
		}
	}
	
	@Override
	public void run() {
		try {
			listening = true;
			
			ClientWorker worker;
			
			while (listening) {
				
				worker = new ClientWorker(this.serverSocket.accept(), proxy);
				worker.start();
				
				workers.add(worker);


				//garbage collector for dead threads
//				for (int i = 0; i < pWorkers.size(); i++) {
//					if (!pWorkers.get(i).isAlive())
//						pWorkers.remove(i);
//				}
			}

		} catch (SocketException e){
			//Gets thrown on shutdown so -> Ignore
		} catch (IOException e) {
			System.out.println(new MessageResponse("Error: An unexpected error occurred!"));
		}
	}
	
	//delete after debug
	public String workerList() {
		
		String workersList = "Worker Threads:";
		
		for (ClientWorker worker : workers) {
			workersList += "\n" + worker.getName() + " Status:" + worker.isAlive();
		}
		
		return workersList;
	}
}
